package juego;

import java.util.ArrayList;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public abstract class Proyectil extends Automata {

	//atributos de clase
	protected static int miRapidez = 10;
	protected static int miTamanio = 1;

	//atributos de instancia
	protected boolean esLeal;

	//metodos

	//constructor. llama al constructor de Automata
	public Proyectil(Coordenada ubicacion) {
		super(ubicacion);
		esLeal = false;//esLeal es false por defecto.
	};


	//pre: recibe como parametros las listas de moviles y de botines.
	//post: actualiza las listas y retorna los puntos que deban computarse
	@Override
	public int vivir(ArrayList<Movil> listaDeMoviles, ArrayList<Botin> listaDeBotines){
		int puntaje = 0;
		//movimiento
		this.movimientoPropio();
		if (this.EstaFueraDelEscenario(this.ubicacion)){
			this.destruirse(listaDeMoviles);
		}else{
		//impacto
		puntaje = this.impactar(listaDeMoviles,listaDeBotines);}
		return puntaje;
	};


	//metodo privado que se encarga de modificar la ubicacion.
	//redefinicion del metodo de Automata
	@Override
	protected void movimientoPropio() {
		int movimiento = miRapidez;
		//si es leal se mueve para arriba
		if (esLeal){
			movimiento = movimiento * -1;
		};
		this.ubicacion.moverEnY(movimiento);
	};

	public void hacerLeal(){
		this.esLeal = true;
	};

	//redefinicion del metodo de Movil
	@Override
	public boolean verLealtad(){
		return this.esLeal;
	};


	//redefinicion del metodo de Movil
	@Override
	public boolean esProyectil(){
		return true;
	};

	@Override
	public boolean esNaveEnemiga(){
		return false;
	};

	public int verTamanio(){
		return miTamanio;
	};

	public int velocidad(){
		return miRapidez;
	};

	//siempre que recibe un impacto es destruido. 
	@Override
	public int recibirImpacto(Impacto impacto, ArrayList<Movil> listaDeMoviles, ArrayList<Botin> listaDeBotines){
		this.vivo = false;
		int puntaje = this.verificarDestruccion(listaDeMoviles, listaDeBotines);
		return puntaje;
	};


	
	//resuelve el choque. retorna el puntaje
	protected int impactoPropio(Movil movil, ArrayList<Movil> listaDeMoviles, ArrayList<Botin> listaDeBotines){
		boolean lealtadPropia = this.esLeal;
		boolean lealtadOtroMovil = movil.verLealtad();
		int puntaje = 0;
		//solo puede impactar moviles enemigos
		if (lealtadPropia != lealtadOtroMovil){
			//no puede impactar proyectiles
			if(!movil.esProyectil()){
				//movil mata a this
				this.vivo = false;
				//movil recibe el impacto. se elimina de la lista si corresponde. se modifica el puntaje
				puntaje += movil.recibirImpacto(this.impactoProvocado(),listaDeMoviles, listaDeBotines);
			}
		}
		return puntaje;
	}
	
	//se encarga de destruirse si corresponde.retorna 0
	protected int verificarDestruccion(ArrayList<Movil> listaDeMoviles, ArrayList<Botin> listaDeBotines){
		if(this.vivo){
			return 0;
		}
		//si no esta vivo se destruye y retorna 0
		this.destruirse(listaDeMoviles);
		return 0;
	}
		
	
	private void persistirEsLeal(Document doc, Element elemento) {
		Boolean valorEsLeal = new Boolean(this.esLeal);
		Element lealtad = doc.createElement("EsLeal");
		elemento.appendChild(lealtad);
		lealtad.setTextContent(valorEsLeal.toString());
	}
	
	protected void persistirProyectil(Document doc, Element elemento) {
		this.persistirEsLeal(doc, elemento);
		this.persistirAutomata(doc, elemento);
	}
	
	private static void recuperarPropios(Element element, Proyectil proyectil) {
		boolean valorLealtad = false;
		NodeList childs = element.getChildNodes();
		for (int i = 0; i < childs.getLength(); i++) {
			Node child = childs.item(i);
			if (child.getNodeName().equals("EsLeal")) {
				valorLealtad = Boolean.parseBoolean(child.getTextContent());
			} 
		}
		proyectil.esLeal = valorLealtad;
	}
	
	protected static void recuperarProyectil(Element element, Proyectil proyectil) {
		recuperarPropios(element, proyectil);
		Automata.recuperarAutomata(element, proyectil);
	}

    
}




